package com.haidechizi.i18n.common.execute;

import com.google.common.collect.Lists;
import com.haidechizi.i18n.common.config.Configuration;
import com.haidechizi.i18n.common.utils.GlobalUtils;
import com.haidechizi.i18n.common.utils.I18nInfoUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 抽象类，用于管理国际化策略
 */
@Slf4j
public abstract class AbstractTranslateExecute implements TranslateExecute {

    private static final String DEFAULT_EXECUTE = "simple";
    private static final Map<String, TranslateExecute> translateExecuteHolder = new ConcurrentHashMap<>(8);
    @Autowired
    protected I18nInfoUtils i18nInfoUtils;
    @Autowired
    private Configuration configuration;

    /**
     * 获取执行器
     *
     * @param name
     * @return
     */
    public static TranslateExecute getTranslateExecute(String name) {
        name = Optional.ofNullable(name).orElse(DEFAULT_EXECUTE);
        return translateExecuteHolder.get(name);
    }

    /**
     * 初始化策略
     */
    @PostConstruct
    public void init() {
        translateExecuteHolder.put(name(), this);
    }

    @Override
    public void assembleI18nInfo(Object model) {
        if (model == null || Objects.equals(model, "")) {
            return;
        }
        if (model instanceof List) {
            processI18nFields((List<Object>) model);
        } else if (model instanceof Map) {

            Collection values = ((Map) model).values();
            ArrayList list = new ArrayList<>(values);
            if (CollectionUtils.isNotEmpty(list)) {
                Object value = list.get(0);
                //如果MAP的值本身就是一个list
                if (value instanceof List) {
                    for (Object val : list) {
                        processI18nFields((List) val);
                    }
                } else {
                    //如果value是一个正常的model
                    processI18nFields(list);
                }
            }
        } else {
            processI18nFields(Lists.newArrayList(model));
        }
    }

    public abstract void processI18nFields(List<Object> models);

    public List<String> extractBusinessKeyList(List<Object> modelList, String businessKey) {
        // 返回set，提出重复元素
        Set<String> businessKeyList = modelList.stream().map(model -> {
            Object businessKeyValue = null;
            try {
                businessKeyValue = FieldUtils.readField(model, businessKey, true);
            } catch (IllegalAccessException e) {
                log.error("error: ", e);
            }
            if (businessKeyValue != null) {
                return String.valueOf(businessKeyValue);
            } else {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toSet());
        return new ArrayList<>(businessKeyList);
    }

    protected boolean isCurrentSystemObject(String systemCode) {
        if (GlobalUtils.skipSystemLimit()) {
            return true;
        }
        if (StringUtils.isBlank(configuration.getCurrentSystemCode())) {
            return true;
        }
        if (configuration.getCurrentSystemCode().equals(systemCode)) {
            return true;
        }
        return false;
    }

}
